﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Coslen.TahorCRM.Domain.Entities.ViewModels.Editing;
using Coslen.TahorCRM.Domain.Entities.ViewModels.Searching;
using Coslen.TahorCRM.Domain.Model.Entities;
using Coslen.TahorCRM.Domain.Services.Interfaces;
using Coslen.TahorCRM.UI.www.Controllers;
using Ninject;

namespace Coslen.TahorCRM.UI.www.Areas.Contacts.Controllers
{
    public class ContactController : TahorBaseController
    {
        [Inject]
        public IContactService ContactService { get; set; }

        //
        // GET: /Contact/
        [Authorize(Roles = "CanEditContact, CanViewContact, CanDeleteContact")]
        public ActionResult Index(ContactSearchViewModel model)
        {
            try
            {
                if (model == null)
                {
                    model = new ContactSearchViewModel();
                    // any defaults???
                }

                model = ContactService.GetContactSearchViewModel(model);

                // Put this into the ViewModel so our Pager can get at these values
                ViewBag.PageSize = model.PageSize;

                // Put the info into the Session so that when we browse away from the page and come back that the last settings are rememberd and used.
               
                return View(model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");
        }

        //
        // GET: /Contact/Details/5
        [Authorize(Roles = "CanEditContact, CanViewContact, CanDeleteContact")]
        public ActionResult Details(int id, string source = "")
        {
            try
            {
                ContactEditViewModel model = ContactService.GetContactEditViewModelById(id);
                model.source = source;
                model.sourceUrl = ConvertSourceToSourceUrl(source, id);
                return View(model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");
        }

        //
        // GET: /Contact/Create
        [Authorize(Roles = "CanEditContact")]
        public ActionResult Create(string source = "")
        {
            try
            {
                ContactEditViewModel model = ContactService.GetNewContactEditViewModel();
                model.source = source;
                model.sourceUrl = ConvertSourceToSourceUrl(source, 0);
                return View(model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");
        }

        //
        // POST: /Contact/Create
        [HttpPost]
        [Authorize(Roles = "CanEditContact")]
        public ActionResult Create(ContactEditViewModel model)
        {
            try
            {
                // TODO: Add insert logic here
                if (ModelState.IsValid)
                {
                    ContactService.SaveContact(model.Contact);
                    return RedirectToAction("Index");
                }
                else
                {
                    ProcessModelState(ModelState);
                }
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            return View(model);
        }

        //
        // GET: /Contact/Edit/5
        [Authorize(Roles = "CanEditContact")]
        public ActionResult Edit(int id, string source = "")
        {
            try
            {
                ContactEditViewModel model = ContactService.GetContactEditViewModelById(id);
                model.source = source;
                model.sourceUrl = ConvertSourceToSourceUrl(source, id);

                return View(model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");
        }

        //
        // POST: /Contact/Edit/5
        [HttpPost]
        [Authorize(Roles = "CanEditContact")]
        public ActionResult Edit(ContactEditViewModel model)
        {
            try
            { 
                // TODO: Add update logic here
                if (ModelState.IsValid)
                {
                    // TODO: Shallow Copy. Why? No child is editable from the view...
                    ContactService.SaveContact(model.Contact);
                    if (!string.IsNullOrEmpty(model.source))
                    {
                        return RedirectToSource(model.source, model.Contact.ContactId);
                    }
                    else
                    {
                        return RedirectToAction("Index");
                    }
                }
                else
                {
                    ProcessModelState(ModelState);

                    ContactEditViewModel failedModel = model;
                    model = ContactService.GetContactEditViewModelById(failedModel.Contact.ContactId);

                    // Only need to get the things that could have been changed from the create / edit view
                    model.Contact.FirstName = failedModel.Contact.FirstName;
                    model.Contact.LastName = failedModel.Contact.LastName;
                    model.Contact.BornOn = failedModel.Contact.BornOn;
                    model.Contact.TitleId = failedModel.Contact.TitleId;
                    model.Contact.GenderId = failedModel.Contact.GenderId;
                }
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            // TODO: add any alter failed edit model logic here....

            return View(model);
        }

        //
        // GET: /Contact/Delete/5
        [Authorize(Roles = "CanDeleteContact")]
        public ActionResult Delete(int id)
        {
            try
            {
                ContactEditViewModel model = ContactService.GetContactEditViewModelById(id);
                return View(model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");
        }

        //
        // POST: /Contact/Delete/5
        [HttpPost, ActionName("Delete")]
        [Authorize(Roles = "CanDeleteContact")]
        public ActionResult DeleteConfirm(int id)
        {
            try
            {
                // TODO: Add delete logic here
                ContactEditViewModel model = ContactService.GetContactEditViewModelById(id);
                ContactService.DeleteContact(model.Contact);
                return RedirectToAction("Index");
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            return RedirectToAction("Delete", new {id = id});
        }

        public ActionResult GetContactSelector(string firstName = "", string lastName = "" )
        {
            return PartialView("_ContactSelector");
        }

        public ActionResult GetContactSelectorSearchResult(string firstName = "", string lastName = "" )
        {

            try
            {
                var model = new ContactSearchViewModel();
                model.FirstName = firstName;
                model.LastName = lastName;
                model = ContactService.GetContactSearchViewModel(model);
                return PartialView("_ContactSelectorSearchResult", model);
            }
            catch (DbEntityValidationException dbEx)
            {
                ProcessDbEntityValidationException(dbEx);
            }
            catch (DbUpdateException dbEx)
            {
                ProcessDbUpdateException(dbEx);
            }
            catch (SqlException sqlEx)
            {
                ProcessSqlException(sqlEx);
            }

            throw new ApplicationException("Should  not be able to get here!");

            
        }

        [HttpPost]
        public ActionResult GetContactSelector(int selectedContactId)
        {
            throw new NotImplementedException();
        }

    }
}
